<?php
/**
 * (logic)
 */
namespace App\Logic\MonthlyReport;

use App\Models\Basics\AmazonCountry;
use App\Models\Basics\ExchangeRate;
use App\Models\Delivery\FBADelivery;
use App\Models\Delivery\FBADeliveryLogistics;
use App\Models\OverSeasIn\Delivery as OSDelivery;
use App\Models\OverSeasIn\DeliveryLogistics as OSDeliveryLogistics;
use App\Models\OverSeasOut\FBADelivery as OSFBADelivery;
use App\Models\OverSeasOut\FBADeliveryLogistics as OSFBADeliveryLogistics;
use App\Models\OverSeasOut\RemovaleDelivery;
use App\Models\OverSeasOut\RemovaleDeliveryLogistics;
use App\Models\Product\ProductPacking;
use Illuminate\Support\Facades\DB;
class CheckLogisticsModify
{
    public static function exe($func)
    {
        try{
            DB::beginTransaction();
            self::{$func}();
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
        }
    }

    private static function _exeAvgPriceRemovaleCHUCANGCheck(){
        RemovaleDelivery::with('detail')
            ->where('status',4)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',1)//已纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds){
                foreach ($ds as $d){
                    $dl = RemovaleDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        echo $d->delivery_no.'-无运费'.PHP_EOL;
                        continue;
                    }
                    $logisticsFee = false;
                    foreach ($d->detail as $_dd){
                        if($_dd->logistics_fee == 0){
                            $logisticsFee = true;
                            break;
                        }
                    }
                    if($logisticsFee) {
                        echo $d->delivery_no.'-平均费用有异常'.PHP_EOL;
                    }
                }
            });
    }

    /**
     * 3.海外仓移库-出仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceRemovaleCHUCANG(){
        $existPs = [];
        $rate = [];
        RemovaleDelivery::with('detail')
            ->where('status',4)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$rate,&$existPs){
                foreach ($ds as $d){
                    $dl = RemovaleDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl) {
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee) && (!$dl->other_fee) && (!$dl->rental_fee) && (!$dl->op_fee) && (!$dl->ex_op_fee)) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $fee = ($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0) + ($dl->rental_fee ?: 0) + ($dl->op_fee ?: 0) + ($dl->ex_op_fee ?: 0);
                    if($dl->type == 1){
                        $date = date('Y-m-01',strtotime($d->delivered_at));
                        $rateKey = $d->country_id.'_'.$date;
                        if(!array_key_exists($rateKey,$rate)){
                            if($d->country_id == 2){//CA
                                $currencyCode = 'USD';
                            }else{
                                $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($d->country_id);
                            }
                            $rate[$rateKey] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($d->delivered_at));
                        }
                        $rateOdds = $rate[$rateKey];
                        $d->avg_price = round(((($rateOdds ?: 0) * $fee) / floatval($sumWeight)),3);
                    }else{
                        $d->avg_price = round($fee / floatval($sumWeight),3);
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    private static function _exeAvgPriceCHUCANGCheck(){
        OSFBADelivery::with('detail')
            ->where('status',3)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',1)//已纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds){
                foreach ($ds as $d){
                    $dl = OSFBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        echo $d->delivery_no.'-无运费'.PHP_EOL;
                        continue;
                    }
                    $logisticsFee = false;
                    foreach ($d->detail as $_dd){
                        if($_dd->logistics_fee == 0){
                            $logisticsFee = true;
                            break;
                        }
                    }
                    if($logisticsFee) {
                        echo $d->delivery_no.'-平均费用有异常'.PHP_EOL;
                    }
                }
            });
    }

    /**
     * 2.2.海外仓中转-出仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceCHUCANG(){
        $existPs = [];
        $rate = [];
        OSFBADelivery::with('detail')
            ->where('status',3)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs,&$rate){
                foreach ($ds as $d){
                    $dl = OSFBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl) {
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee) && (!$dl->other_fee) && (!$dl->rental_fee) && (!$dl->op_fee) && (!$dl->ex_op_fee)) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $fee = ($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0) + ($dl->rental_fee ?: 0) + ($dl->op_fee ?: 0) + ($dl->ex_op_fee ?: 0);
                    if($dl->type == 1){
                        $date = date('Y-m-01',strtotime($d->delivered_at));
                        $rateKey = $d->country_id.'_'.$date;
                        if(!array_key_exists($rateKey,$rate)){
                            if($d->country_id == 2){//CA
                                $currencyCode = 'USD';
                            }else{
                                $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($d->country_id);
                            }
                            $rate[$rateKey] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($d->delivered_at));
                        }
                        $rateOdds = $rate[$rateKey];
                        $d->avg_price = round(((($rateOdds ?: 0) * $fee) / floatval($sumWeight)),3);
                    }else{
                        $d->avg_price = round($fee / floatval($sumWeight),3);
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    private static function _exeAvgPriceRUCANGCheck(){
        OSDelivery::with('detail')
            ->where('status','>=',6)//已发货或已入海外仓中转仓
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',1)//已纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds){
                foreach ($ds as $d){
                    $dl = OSDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        echo $d->delivery_no.'-无运费'.PHP_EOL;
                        continue;
                    }
                    $logisticsFee = false;
                    foreach ($d->detail as $_dd){
                        if($_dd->logistics_fee == 0){
                            $logisticsFee = true;
                            break;
                        }
                    }
                    if($logisticsFee) {
                        echo $d->delivery_no.'-平均费用有异常'.PHP_EOL;
                    }
                }
            });
    }

    /**
     * 2.1.海外仓(全平台的中转,代发）-入仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceRUCANG(){
        $existPs = [];
        OSDelivery::with('detail')
            ->where('status','>=',6)//已发货或已入海外仓中转仓
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs){
                foreach ($ds as $d){
                    $dl = OSDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee) && (!$dl->other_fee)) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->avg_price = round(((($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0)) / floatval($sumWeight)),3);
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    private static function _exeAvgPriceCheck(){
        FBADelivery::with('detail')
            ->where('status',6)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',1)//已纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds){
                foreach ($ds as $d){
                    $dl = FBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        echo $d->delivery_no.'-无运费'.PHP_EOL;
                        continue;
                    }
                    $logisticsFee = false;
//                    echo '发货单：'.$d->delivery_no.PHP_EOL;
                    foreach ($d->detail as $_dd){
                        if($_dd->logistics_fee == 0){
                            $logisticsFee = true;
                            break;
                        }
                    }
                    if($logisticsFee) {
                        echo $d->delivery_no.'-平均费用有异常'.PHP_EOL;
                    }
                }
            });
    }

    /**
     * 1.国内仓发往FBA
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPrice(){
        $existPs = [];
        FBADelivery::with('detail')
            ->where('status',6)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs){
                foreach ($ds as $d){
                    $dl = FBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee) && (!$dl->other_fee)) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->avg_price = round(((($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0)) / floatval($sumWeight)),3);
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
        });
    }
}
